package com.example.service;

import com.example.model.Role;
import com.example.model.Permission;
import com.example.repository.RoleRepository;
import com.example.repository.PermissionRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@Transactional
public class RoleServiceImpl implements RoleService {
    
    @Autowired
    private RoleRepository roleRepository;
    
    @Autowired
    private PermissionRepository permissionRepository;
    
    @Override
    public Role createRole(Role role) {
        if (existsByCode(role.getCode())) {
            throw new RuntimeException("角色代码已存在: " + role.getCode());
        }
        if (existsByName(role.getName())) {
            throw new RuntimeException("角色名称已存在: " + role.getName());
        }
        return roleRepository.save(role);
    }
    
    @Override
    public Role updateRole(Role role) {
        if (!roleRepository.existsById(role.getId())) {
            throw new RuntimeException("角色不存在");
        }
        
        // 检查代码和名称是否与其他角色冲突
        Optional<Role> existingByCode = roleRepository.findByCode(role.getCode());
        if (existingByCode.isPresent() && !existingByCode.get().getId().equals(role.getId())) {
            throw new RuntimeException("角色代码已存在: " + role.getCode());
        }
        
        Optional<Role> existingByName = roleRepository.findByName(role.getName());
        if (existingByName.isPresent() && !existingByName.get().getId().equals(role.getId())) {
            throw new RuntimeException("角色名称已存在: " + role.getName());
        }
        
        return roleRepository.save(role);
    }
    
    @Override
    public void deleteRole(Long id) {
        if (!canDeleteRole(id)) {
            throw new RuntimeException("该角色不能删除");
        }
        roleRepository.deleteById(id);
    }
    
    @Override
    public Optional<Role> findById(Long id) {
        return roleRepository.findById(id);
    }
    
    @Override
    public Optional<Role> findByCode(String code) {
        return roleRepository.findByCode(code);
    }
    
    @Override
    public Optional<Role> findByName(String name) {
        return roleRepository.findByName(name);
    }
    
    @Override
    public List<Role> findAllActiveRoles() {
        return roleRepository.findByIsActiveTrueOrderByName();
    }
    
    @Override
    public Page<Role> findAllActiveRoles(Pageable pageable) {
        return roleRepository.findByIsActiveTrue(pageable);
    }
    
    @Override
    public List<Role> findSystemRoles() {
        return roleRepository.findByIsSystemTrue();
    }
    
    @Override
    public List<Role> findNonSystemRoles() {
        return roleRepository.findByIsSystemFalse();
    }
    
    @Override
    public List<Role> searchRolesByName(String name) {
        return roleRepository.findByNameContainingAndIsActiveTrue(name);
    }
    
    @Override
    public Set<Permission> getRolePermissions(Long roleId) {
        Optional<Role> roleOpt = roleRepository.findById(roleId);
        if (roleOpt.isPresent()) {
            return roleOpt.get().getPermissions();
        }
        return new HashSet<>();
    }
    
    @Override
    public void assignPermissionsToRole(Long roleId, Set<Long> permissionIds) {
        Optional<Role> roleOpt = roleRepository.findById(roleId);
        if (roleOpt.isPresent()) {
            Role role = roleOpt.get();
            Set<Permission> permissions = permissionIds.stream()
                    .map(id -> permissionRepository.findById(id))
                    .filter(Optional::isPresent)
                    .map(Optional::get)
                    .collect(Collectors.toSet());
            
            if (role.getPermissions() == null) {
                role.setPermissions(new HashSet<>());
            }
            role.getPermissions().addAll(permissions);
            roleRepository.save(role);
        }
    }
    
    @Override
    public void removePermissionsFromRole(Long roleId, Set<Long> permissionIds) {
        Optional<Role> roleOpt = roleRepository.findById(roleId);
        if (roleOpt.isPresent()) {
            Role role = roleOpt.get();
            if (role.getPermissions() != null) {
                role.getPermissions().removeIf(permission -> permissionIds.contains(permission.getId()));
                roleRepository.save(role);
            }
        }
    }
    
    @Override
    public void updateRolePermissions(Long roleId, Set<Long> permissionIds) {
        Optional<Role> roleOpt = roleRepository.findById(roleId);
        if (roleOpt.isPresent()) {
            Role role = roleOpt.get();
            Set<Permission> permissions = permissionIds.stream()
                    .map(id -> permissionRepository.findById(id))
                    .filter(Optional::isPresent)
                    .map(Optional::get)
                    .collect(Collectors.toSet());
            
            role.setPermissions(permissions);
            roleRepository.save(role);
        }
    }
    
    @Override
    public Role activateRole(Long id) {
        Optional<Role> roleOpt = roleRepository.findById(id);
        if (roleOpt.isPresent()) {
            Role role = roleOpt.get();
            role.setIsActive(true);
            return roleRepository.save(role);
        }
        throw new RuntimeException("角色不存在");
    }
    
    @Override
    public Role deactivateRole(Long id) {
        Optional<Role> roleOpt = roleRepository.findById(id);
        if (roleOpt.isPresent()) {
            Role role = roleOpt.get();
            if (role.getIsSystem()) {
                throw new RuntimeException("系统角色不能停用");
            }
            role.setIsActive(false);
            return roleRepository.save(role);
        }
        throw new RuntimeException("角色不存在");
    }
    
    @Override
    public Long countActiveRoles() {
        return roleRepository.countActiveRoles();
    }
    
    @Override
    public RoleStatistics getRoleStatistics() {
        Long totalRoles = roleRepository.count();
        Long activeRoles = roleRepository.countActiveRoles();
        Long systemRoles = (long) roleRepository.findByIsSystemTrue().size();
        Long customRoles = totalRoles - systemRoles;
        
        return new RoleStatistics(totalRoles, activeRoles, systemRoles, customRoles);
    }
    
    @Override
    public boolean existsByCode(String code) {
        return roleRepository.findByCode(code).isPresent();
    }
    
    @Override
    public boolean existsByName(String name) {
        return roleRepository.findByName(name).isPresent();
    }
    
    @Override
    public boolean canDeleteRole(Long id) {
        Optional<Role> roleOpt = roleRepository.findById(id);
        if (roleOpt.isPresent()) {
            Role role = roleOpt.get();
            // 系统角色不能删除
            return !role.getIsSystem();
        }
        return false;
    }
}
